/* dCache - http://www.dcache.org/
*
* Copyright (C) 2015 Deutsches Elektronen-Synchrotron
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.dcache.dss;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableSet;
import eu.emi.security.authn.x509.X509Credential;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLParameters;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.security.cert.CertificateFactory;
import java.util.Set;
import org.dcache.gsi.ClientGsiEngine;
import org.dcache.ssl.SslContextFactory;
import org.dcache.util.CertificateFactories;
import static com.google.common.base.Predicates.in;
import static com.google.common.base.Predicates.not;
import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Iterables.toArray;
import static java.util.Arrays.asList;
public class ClientGsiEngineDssContextFactory implements DssContextFactory
{
private final CertificateFactory cf;
private final Set<String> bannedCiphers;
private final Set<String> bannedProtocols;
private final SslContextFactory contextFactory;
private final boolean isDelegationEnabled;
private final boolean isDelegationLimited;
private final X509Credential credential;
public ClientGsiEngineDssContextFactory(SslContextFactory contextFactory, X509Credential credential,
String[] bannedCiphers,
boolean isDelegationEnabled, boolean isDelegationLimited)
{
this.cf = CertificateFactories.newX509CertificateFactory();
this.credential = credential;
this.contextFactory = contextFactory;
this.isDelegationEnabled = isDelegationEnabled;
this.isDelegationLimited = isDelegationLimited;
this.bannedCiphers = ImmutableSet.copyOf(bannedCiphers);
this.bannedProtocols = ImmutableSet.of("SSL", "SSLv2", "SSLv2Hello", "SSLv3");
}
@Override
public DssContext create(InetSocketAddress remoteSocketAddress, InetSocketAddress localSocketAddress)
throws IOException
{
try {
SSLEngine delegate =
contextFactory.getContext(credential).createSSLEngine(
remoteSocketAddress.getHostString(),
remoteSocketAddress.getPort());
SSLParameters sslParameters = delegate.getSSLParameters();
String[] cipherSuites = toArray(filter(asList(sslParameters.getCipherSuites()), not(in(bannedCiphers))), String.class);
String[] protocols = toArray(filter(asList(sslParameters.getProtocols()), not(in(bannedProtocols))), String.class);
sslParameters.setCipherSuites(cipherSuites);
sslParameters.setProtocols(protocols);
sslParameters.setWantClientAuth(true);
sslParameters.setNeedClientAuth(true);
delegate.setSSLParameters(sslParameters);
ClientGsiEngine engine = new ClientGsiEngine(delegate, credential, isDelegationEnabled, isDelegationLimited);
return new SslEngineDssContext(engine, cf);
} catch (Exception e) {
Throwables.propagateIfPossible(e, IOException.class);
throw new IOException("Failed to create SSL engine: " + e.getMessage(), e);
}
}
}